"""摄像头管理器模块"""

import logging
from datetime import datetime
from typing import Dict, Optional, List, Any
from video_processing.video_capture import VideoCapture
from config import get_camera_config

# 配置日志记录器
logger = logging.getLogger(__name__)

class CameraManager:
    """摄像头管理器，负责管理多个视频源"""
    
    def __init__(self):
        """初始化摄像头管理器"""
        self.cameras: Dict[str, VideoCapture] = {}
        self.active_camera_name: Optional[str] = None
        
        # 从配置加载摄像头
        self._load_cameras_from_config()
    
    def _load_cameras_from_config(self) -> None:
        """从配置文件加载摄像头"""
        try:
            camera_configs = get_camera_config()
            
            for camera_config in camera_configs:
                try:
                    camera_id = camera_config.get('id', 0)
                    camera_name = camera_config.get('name', f'camera_{camera_id}')
                    camera_source = camera_config.get('source', 0)
                    
                    # 创建摄像头实例
                    self.add_camera(camera_name, camera_source)
                    
                    # 如果配置了默认摄像头，则设置为活动摄像头
                    if camera_config.get('default', False):
                        self.set_active_camera(camera_name)
                        
                except Exception as e:
                    logger.error(f"加载摄像头配置失败: {e}")
            
            # 如果没有设置活动摄像头且存在摄像头，则设置第一个为活动摄像头
            if self.active_camera_name is None and self.cameras:
                first_camera = next(iter(self.cameras.keys()))
                self.set_active_camera(first_camera)
        except Exception as e:
            logger.error(f"从配置文件加载摄像头失败: {e}")
        
        # 如果没有设置活动摄像头且存在摄像头，则设置第一个为活动摄像头
        if self.active_camera_name is None and self.cameras:
            first_camera = next(iter(self.cameras.keys()))
            self.set_active_camera(first_camera)
    
    def add_camera(self, name: str, source: any) -> bool:
        """添加新摄像头
        
        Args:
            name: 摄像头名称
            source: 视频源
            
        Returns:
            是否添加成功
        """
        logger.info(f"尝试添加摄像头 '{name}'，源: {source}")
        try:
            # 如果摄像头已存在，先停止它
            if name in self.cameras:
                logger.info(f"摄像头 '{name}' 已存在，将替换")
                self.stop_camera(name)
                del self.cameras[name]
            
            # 创建新的摄像头实例
            camera = VideoCapture(source=source, name=name)
            self.cameras[name] = camera
            
            # 如果这是第一个摄像头，自动设置为活动摄像头
            if len(self.cameras) == 1:
                self.active_camera_name = name
                logger.info(f"摄像头 '{name}' 已设为活动摄像头")
            
            logger.info(f"摄像头 '{name}' 已成功添加，当前共有 {len(self.cameras)} 个摄像头")
            return True
            
        except Exception as e:
            logger.error(f"添加摄像头 '{name}' 失败: {str(e)}", exc_info=True)
            return False
    
    def remove_camera(self, name: str) -> bool:
        """移除摄像头
        
        Args:
            name: 摄像头名称
            
        Returns:
            是否移除成功
        """
        try:
            if name in self.cameras:
                # 停止摄像头
                self.stop_camera(name)
                
                # 移除摄像头
                del self.cameras[name]
                
                # 如果移除的是活动摄像头，尝试切换到另一个
                if name == self.active_camera_name:
                    if self.cameras:
                        self.active_camera_name = next(iter(self.cameras.keys()))
                        logger.info(f"自动切换活动摄像头为: {self.active_camera_name}")
                    else:
                        self.active_camera_name = None
                
                logger.info(f"摄像头 '{name}' 已移除")
                return True
            else:
                logger.warning(f"摄像头 '{name}' 不存在")
                return False
                
        except Exception as e:
            logger.error(f"移除摄像头 '{name}' 失败: {e}")
            return False
    
    def start_camera(self, name: str) -> bool:
        """启动摄像头
        
        Args:
            name: 摄像头名称
            
        Returns:
            是否启动成功
        """
        try:
            if name in self.cameras:
                success = self.cameras[name].start()
                if success:
                    logger.info(f"摄像头 '{name}' 启动成功")
                else:
                    logger.warning(f"摄像头 '{name}' 启动失败")
                return success
            else:
                logger.warning(f"摄像头 '{name}' 不存在")
                return False
        except Exception as e:
            logger.error(f"启动摄像头 '{name}' 时发生错误: {e}")
            return False
    
    def stop_camera(self, name: str) -> bool:
        """停止摄像头
        
        Args:
            name: 摄像头名称
            
        Returns:
            是否停止成功
        """
        try:
            if name in self.cameras:
                self.cameras[name].stop()
                logger.info(f"摄像头 '{name}' 已停止")
                return True
            else:
                logger.warning(f"摄像头 '{name}' 不存在")
                return False
        except Exception as e:
            logger.error(f"停止摄像头 '{name}' 时发生错误: {e}")
            return False
    
    def start_all_cameras(self) -> bool:
        """启动所有摄像头
        
        Returns:
            是否全部启动成功
        """
        logger.info(f"尝试启动所有 {len(self.cameras)} 个摄像头")
        all_success = True
        success_count = 0
        failed_count = 0
        failed_cameras = []
        
        for name in self.cameras.keys():
            if self.start_camera(name):
                success_count += 1
            else:
                all_success = False
                failed_count += 1
                failed_cameras.append(name)
        
        logger.info(f"摄像头启动完成: 成功 {success_count}, 失败 {failed_count}")
        if failed_cameras:
            logger.warning(f"以下摄像头启动失败: {', '.join(failed_cameras)}")
            
        return all_success
    
    def stop_all_cameras(self) -> None:
        """停止所有摄像头"""
        logger.info(f"尝试停止所有 {len(self.cameras)} 个摄像头")
        for name in self.cameras.keys():
            self.stop_camera(name)
        logger.info("所有摄像头停止操作已完成")
    
    def set_active_camera(self, name: str) -> bool:
        """设置活动摄像头
        
        Args:
            name: 摄像头名称
            
        Returns:
            是否设置成功
        """
        try:
            if name in self.cameras:
                self.active_camera_name = name
                
                # 如果活动摄像头未启动，尝试启动它
                if not self.cameras[name].running:
                    self.start_camera(name)
                    
                logger.info(f"活动摄像头已切换为: {name}")
                return True
            else:
                logger.warning(f"摄像头 '{name}' 不存在")
                return False
        except Exception as e:
            logger.error(f"设置活动摄像头 '{name}' 时发生错误: {e}")
            return False
    
    def get_active_camera(self) -> Optional[VideoCapture]:
        """获取当前活动的摄像头
        
        Returns:
            VideoCapture实例，如果没有活动摄像头则返回None
        """
        try:
            if self.active_camera_name and self.active_camera_name in self.cameras:
                camera = self.cameras[self.active_camera_name]
                logger.debug(f"获取活动摄像头: {self.active_camera_name}")
                return camera
            else:
                logger.debug("没有活动摄像头")
                return None
        except Exception as e:
            logger.error(f"获取活动摄像头时发生错误: {e}")
            return None
    
    def get_camera(self, name: str) -> Optional[VideoCapture]:
        """获取指定名称的摄像头
        
        Args:
            name: 摄像头名称
            
        Returns:
            VideoCapture实例，如果摄像头不存在则返回None
        """
        try:
            camera = self.cameras.get(name)
            if camera:
                logger.debug(f"获取摄像头: {name}")
            else:
                logger.debug(f"摄像头 '{name}' 不存在")
            return camera
        except Exception as e:
            logger.error(f"获取摄像头 '{name}' 时发生错误: {e}")
            return None
    
    def list_cameras(self) -> List[str]:
        """列出所有摄像头
        
        Returns:
            摄像头名称列表
        """
        try:
            camera_list = list(self.cameras.keys())
            logger.debug(f"列出所有摄像头: {camera_list}")
            return camera_list
        except Exception as e:
            logger.error(f"列出摄像头时发生错误: {e}")
            return []
    
    def get_active_camera_name(self) -> Optional[str]:
        """获取当前活动摄像头的名称
        
        Returns:
            活动摄像头名称，如果没有活动摄像头则返回None
        """
        try:
            logger.debug(f"获取活动摄像头名称: {self.active_camera_name}")
            return self.active_camera_name
        except Exception as e:
            logger.error(f"获取活动摄像头名称时发生错误: {e}")
            return None
    
    def get_camera_status(self, name: str) -> Optional[Dict]:
        """获取摄像头状态
        
        Args:
            name: 摄像头名称
            
        Returns:
            状态信息字典
        """
        try:
            camera = self.get_camera(name)
            if camera:
                try:
                    status = camera.get_status()
                    logger.debug(f"获取摄像头 '{name}' 状态: {status}")
                    return status
                except Exception as e:
                    logger.error(f"获取摄像头 '{name}' 状态时发生错误: {e}")
                    # 返回基本状态信息作为后备
                    return {
                        'status': 'error',
                        'error': str(e),
                        'name': name
                    }
            else:
                logger.warning(f"无法获取摄像头 '{name}' 状态: 摄像头不存在")
                return None
        except Exception as e:
            logger.error(f"获取摄像头状态时发生未预期错误: {e}")
            return None
    
    def update_camera_source(self, name: str, new_source: any) -> bool:
        """更新摄像头源
        
        Args:
            name: 摄像头名称
            new_source: 新的视频源
            
        Returns:
            是否更新成功
        """
        if name in self.cameras:
            try:
                # 停止当前摄像头
                self.stop_camera(name)
                
                # 更新源并重启
                self.cameras[name] = VideoCapture(source=new_source, name=name)
                
                # 如果是活动摄像头，重新启动它
                if name == self.active_camera_name:
                    self.start_camera(name)
                    
                logger.info(f"摄像头 '{name}' 源已更新")
                return True
            except Exception as e:
                logger.error(f"更新摄像头 '{name}' 源失败: {e}")
                return False
        else:
            logger.warning(f"摄像头 '{name}' 不存在")
            return False
    
    def reload_cameras(self) -> None:
        """重新加载摄像头配置"""
        try:
            logger.info("开始重新加载摄像头配置...")
            # 停止所有摄像头
            self.stop_all_cameras()
            
            # 清空摄像头列表
            self.cameras.clear()
            self.active_camera_name = None
            
            # 重新加载
            self._load_cameras_from_config()
            logger.info(f"摄像头配置重新加载完成，共加载 {len(self.cameras)} 个摄像头")
        except Exception as e:
            logger.error(f"重新加载摄像头配置失败: {e}")
    
    def get_all_cameras(self) -> Dict[str, Dict[str, Any]]:
        """获取所有摄像头及其配置信息
        
        Returns:
            包含所有摄像头信息的字典
        """
        try:
            logger.debug(f"获取所有摄像头信息，共 {len(self.cameras)} 个摄像头")
            camera_info = {}
            
            for name, camera in self.cameras.items():
                try:
                    camera_info[name] = {
                        'name': name,
                        'is_active': name == self.active_camera_name,
                        'is_running': camera.running if hasattr(camera, 'running') else False,
                        'status': self.get_camera_status(name)
                    }
                except Exception as e:
                    logger.error(f"获取摄像头 '{name}' 信息时发生错误: {e}")
                    # 添加错误信息，但继续处理其他摄像头
                    camera_info[name] = {
                        'name': name,
                        'is_active': name == self.active_camera_name,
                        'status': {'status': 'error', 'error': str(e)}
                    }
                    
            return camera_info
        except Exception as e:
            logger.error(f"获取所有摄像头信息时发生错误: {e}")
            return {}
    
    def get_active_cameras(self) -> List[str]:
        """获取所有活动中的摄像头名称列表
        
        Returns:
            活动中的摄像头名称列表
        """
        try:
            active_cameras = []
            
            for name, camera in self.cameras.items():
                try:
                    if hasattr(camera, 'running') and camera.running:
                        active_cameras.append(name)
                except Exception as e:
                    logger.error(f"检查摄像头 '{name}' 运行状态时发生错误: {e}")
                    # 出错时不将该摄像头视为活动状态，但继续检查其他摄像头
            
            logger.debug(f"找到 {len(active_cameras)} 个活动中的摄像头: {active_cameras}")
            return active_cameras
        except Exception as e:
            logger.error(f"获取活动摄像头列表时发生错误: {e}")
            return []
    
    def initialize(self) -> bool:
        """初始化摄像头管理器（提供兼容性）
        
        Returns:
            是否初始化成功
        """
        logger.info("开始初始化摄像头管理器...")
        try:
            # 检查配置文件是否存在并重新加载
            self.reload_cameras()
            logger.info(f"摄像头管理器初始化成功，已加载 {len(self.cameras)} 个摄像头")
            return True
        except Exception as e:
            logger.error(f"初始化摄像头管理器失败: {e}")
            return False
    
    def get_health_status(self) -> Dict[str, Any]:
        """获取摄像头管理器健康状态
        
        Returns:
            健康状态信息
        """
        try:
            total_cameras = len(self.cameras)
            active_cameras = self.get_active_cameras()
            active_count = len(active_cameras)
            inactive_count = total_cameras - active_count
            
            health_status = {
                'total_cameras': total_cameras,
                'active_cameras': active_cameras,
                'active_count': active_count,
                'inactive_count': inactive_count,
                'current_active_camera': self.active_camera_name,
                'status': 'healthy' if total_cameras == 0 or active_count > 0 else 'degraded',
                'timestamp': datetime.now().isoformat()
            }
            
            logger.debug(f"摄像头管理器健康状态: {health_status}")
            return health_status
        except Exception as e:
            logger.error(f"获取摄像头管理器健康状态时发生错误: {e}")
            return {
                'status': 'error',
                'error': str(e),
                'timestamp': datetime.now().isoformat()
            }

# 创建全局摄像头管理器实例
camera_manager = CameraManager()

# 导出常用方法
def get_active_camera() -> Optional[VideoCapture]:
    """获取当前活动摄像头的快捷方法"""
    try:
        return camera_manager.get_active_camera()
    except Exception as e:
        logger.error(f"调用快捷方法获取活动摄像头失败: {e}")
        return None

def set_active_camera(name: str) -> bool:
    """设置活动摄像头的快捷方法"""
    try:
        return camera_manager.set_active_camera(name)
    except Exception as e:
        logger.error(f"调用快捷方法设置活动摄像头失败: {e}")
        return False

def list_available_cameras() -> List[str]:
    """列出所有可用摄像头的快捷方法"""
    try:
        return camera_manager.list_cameras()
    except Exception as e:
        logger.error(f"调用快捷方法列出摄像头失败: {e}")
        return []